// 104min used
#include "kernel/fcntl.h"
#include "kernel/types.h"
#include "kernel/fs.h"
#include "kernel/stat.h"
#include "user/user.h"

// return 1 if is target
int is_target(const char *current_str, const char *target) {
  const char *p = current_str + strlen(current_str);
  while (p >= current_str && *p != '/') {
    --p;
  }
  return strcmp(p + 1, target) == 0;
}

void find(const char *root_path, const char *target) {
  int fd;
  struct dirent de;
  struct stat st;

  if ((fd = open(root_path, O_RDONLY)) < 0) {
    fprintf(2, "find: cannot open %s\n", root_path);
    return;
  }

  if (fstat(fd, &st) < 0) {
    fprintf(2, "find: cannot stat %s\n", root_path);
    close(fd);
    return;
  }

  if (is_target(root_path, target)) {
    printf("%s\n", root_path);
  }

  if (st.type == T_DIR) {
    char buf[512];
    strcpy(buf, root_path);
    char *p = buf + strlen(buf);
    *p++ = '/';
    char *const q = p;
    while (read(fd, &de, sizeof(de)) == sizeof(de)) {
      if (de.inum == 0 || strcmp(de.name, ".") == 0 ||
          strcmp(de.name, "..") == 0) {
        continue;
      }
      strcpy(p, de.name);
      find(buf, target);
      p = q;
    }
  }
  close(fd);
}

int main(int argc, char *argv[]) {
  if (argc < 2) {
    fprintf(2, "find: missing parameters\n");
  } else if (argc == 2) {
    find(".", argv[1]);
  } else {
    for (int i = 2; i < argc; ++i) {
      find(argv[1], argv[i]);
    }
  }

  exit(0);
}
